//
// Created by 徐套 on 2023/9/29.
//

#include "main_server.h"


void main_server::start_server() {
    start = true;
    std::cout<<"start main server"<<std::endl;
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(ip);
    server_addr.sin_port = htons(listen_port);
    std::cout << "ip:" << ip<<",port:"<<listen_port<< std::endl;
    if (bind(m_listen_socket, (struct sockaddr *)(&server_addr), sizeof(server_addr)) != -1){
        std::cout << "Listen on " << inet_ntoa(server_addr.sin_addr) << ":" << ntohs(server_addr.sin_port) << "\n";
    }
    if (listen(m_listen_socket, max_server) != -1)
        std::cout << "start listen port" << std::endl;

    // 心跳包监听程序

    std::thread alive(&main_server::car_server_is_alive, this);
    alive.detach();
    listen_client();
}

void main_server::listen_client() {
    while (start) {
        try {
            // 忽略connect错误信号
            signal(SIGPIPE, SIG_IGN);

            struct sockaddr_in client_addr;
            socklen_t client_addrlen = sizeof(client_addr);
            int client_fd = accept(m_listen_socket, (struct sockaddr *) &client_addr, &client_addrlen);
            std::cout << "start accept connect" << std::endl;
            std::string this_client_ip = inet_ntoa(client_addr.sin_addr);
            unsigned int this_client_port = ntohs(client_addr.sin_port);
            // 验证服务器
            char identity_information[4] = "who";
            send(client_fd, identity_information, 4, 0);
            char recv_identity[6] = {0};
            recv(client_fd, recv_identity, sizeof(recv_identity), 0);
            std::cout << recv_identity << std::endl;
            // 01代表car，10代表upper computer，01001表示车 001号
            if (recv_identity[0] == '0' && recv_identity[1] == '1') {
                std::shared_ptr<cloud_server> server(new cloud_server(this_client_ip.c_str(), this_client_port, client_fd, &time_));
                server->name_sign = recv_identity;
                char *suc;
                if (server->init_server()) {
//                connection.insert(std::map<int, int>::value_type (client_fd, client_fd));
                    suc = "success";
                    server->send_msg_by_tcp(suc);
                    std::cout << "success to init car server " << client_fd << std::endl;
                    server->begin();
                    car->add_car_server(server);

                    // 返回上位机信息
                } else {
                    suc = "fail";
//                connection.erase(client_fd);
                    server->send_msg_by_tcp(suc);
                    std::cout << "fail to init car server " << client_fd << std::endl;
                    // 返回上位机报错
                }
            } else if (recv_identity[0] == '1' && recv_identity[1] == '0') {
                std::shared_ptr<upper_computer_server> upper (new upper_computer_server(this_client_port, client_fd, this_client_ip, &time_, car));
                std::cout << "start init upper server" << std::endl;
                if (upper->init_upper_server()) {
                    if (upper_server != nullptr) {
                        upper_server = upper;
                    } else {
                        upper_server = upper;
                    }
//                connection.insert(std::map<int, int>::value_type (client_fd, client_fd));
                    std::cout << "success to init upper computer server " << client_fd << std::endl;
                    // 返回上位机信息

                } else {
//                connection.erase(client_fd);
                    std::cout << "fail to init upper computer server " << client_fd << std::endl;

                    // 返回上位机报错

                }
            }
        }catch (...){
            std::cout<<"socket error"<<std::endl;
        }

    }
}

void main_server::car_server_is_alive() {
    std::string msg;
    std::string time00;
    while (start){
        sleep(1);
        if (car->have_car_server()) {

            // 检测车辆服务器
            msg = car->is_alive();
            send_msg_to_upper_by_tcp(msg);
            car->alive();

            // 检测上位机服务器

            // 检测延时
            time00 = car->get_time_late();
            send_msg_to_upper_by_tcp(time00);
        }
        if (upper_server != nullptr){
            if (!upper_server->is_alive()) {
                upper_server = nullptr;
            }
        }
    }
}

void main_server::send_msg_to_upper_by_tcp(std::string msg) {
    if (!upper_server)
        return;
    else{
        upper_server->send_msg_by_tcp(msg);
        }
}